package helper

import (
	"strconv"
	"strings"

	"mall/service/wpgql/api/internal/graph/model"
	"mall/service/wpgql/api/internal/graph/util"
)

func GetBlogLayoutMenuFilter(id string, idType *model.MenuNodeIDTypeEnum) string {
	if idType == nil {
		return ""
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogLayoutMenu]
	if !hasEntitySettings {
		return ""
	}

	whereMap := make(map[string]map[string][]string)

	switch *idType {
	case model.MenuNodeIDTypeEnumDatabaseID:
		columnSetting, hasColumnSetting := entitySettings["databaseId"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	case model.MenuNodeIDTypeEnumID:
		columnSetting, hasColumnSetting := entitySettings["id"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.MenuNodeIDTypeEnumName:
		columnSetting, hasColumnSetting := entitySettings["name"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	}

	return ConnectionWhereMapToString(whereMap)
}

func GetBlogPostFilter(id string, idType *model.PostIDType) string {
	if idType == nil {
		return ""
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogPost]
	if !hasEntitySettings {
		return ""
	}

	whereMap := make(map[string]map[string][]string)

	switch *idType {
	case model.PostIDTypeDatabaseID:
		columnSetting, hasColumnSetting := entitySettings["databaseId"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	case model.PostIDTypeID:
		columnSetting, hasColumnSetting := entitySettings["id"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.PostIDTypeSlug:
		if strings.HasPrefix(id, "login") || strings.HasPrefix(id, "admin") {
			return ""
		}

		columnSetting, hasColumnSetting := entitySettings["slug"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.PostIDTypeURI:
		if strings.HasPrefix(id, "login") || strings.HasPrefix(id, "admin") {
			return ""
		}

		columnSetting, hasColumnSetting := entitySettings["uri"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	}

	return ConnectionWhereMapToString(whereMap)
}

func GetBlogPostConnectionFilterMap(m *model.RootQueryToPostConnectionWhereArgs) map[string]string { // 未完成
	if m == nil {
		return nil
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogPost]
	if !hasEntitySettings {
		return nil
	}

	whereMap := make(map[string]map[string][]string)
	var preWhereEntityName string
	preWhereMap := make(map[string]map[string][]string)
	if columnSetting, hasColumnSetting := entitySettings["databaseId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.ID != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], strconv.Itoa(*m.ID))
		}
		if m.In != nil && len(m.In) > 0 {
			var sa []string
			for _, s := range m.In {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.NotIn != nil && len(m.NotIn) > 0 {
			var sa []string
			for _, s := range m.NotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["parentDatabaseId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Parent != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Parent)
		}
		if m.ParentIn != nil && len(m.ParentIn) > 0 {
			var sa []string
			for _, s := range m.ParentIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.ParentNotIn != nil && len(m.ParentNotIn) > 0 {
			var sa []string
			for _, s := range m.ParentNotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["uri"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Name != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Name)
		}
		if m.NameIn != nil && len(m.NameIn) > 0 {
			var sa []string
			for _, s := range m.NameIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["authorId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Author != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], strconv.Itoa(*m.Author))
		}
		if m.AuthorIn != nil && len(m.AuthorIn) > 0 {
			var sa []string
			for _, s := range m.AuthorIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.AuthorNotIn != nil && len(m.AuthorNotIn) > 0 {
			var sa []string
			for _, s := range m.AuthorNotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["title"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Title != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Title)
		}
	}
	if preWhereEntityName == "" && m.AuthorName != nil {
		if columnSetting, hasColumnSetting := entitySettings["authorName"]; hasColumnSetting {
			preWhereEntityName = columnSetting.RpcEntityName
			preWhereMap[columnSetting.Name] = map[string][]string{
				"equalTo": []string{*m.AuthorName},
			}
		}
	}
	if preWhereEntityName == "" && m.CategoryName != nil {
		if columnSetting, hasColumnSetting := entitySettings["categoryName"]; hasColumnSetting {
			preWhereEntityName = columnSetting.RpcEntityName
			preWhereMap[columnSetting.Name] = map[string][]string{
				"equalTo": []string{*m.CategoryName},
			}
		}
	}

	return map[string]string{
		"filter": ConnectionWhereMapToString(whereMap),
		"preFilterEntity": preWhereEntityName,
		"preFilter": ConnectionWhereMapToString(preWhereMap),
	}
}

func GetBlogPageFilter(id string, idType *model.PageIDType) string {
	if idType == nil {
		return ""
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogPage]
	if !hasEntitySettings {
		return ""
	}

	whereMap := make(map[string]map[string][]string)

	switch *idType {
	case model.PageIDTypeDatabaseID:
		columnSetting, hasColumnSetting := entitySettings["databaseId"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	case model.PageIDTypeID:
		columnSetting, hasColumnSetting := entitySettings["id"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.PageIDTypeURI:
		if strings.HasPrefix(id, "login") || strings.HasPrefix(id, "admin") {
			return ""
		}

		columnSetting, hasColumnSetting := entitySettings["uri"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	}

	return ConnectionWhereMapToString(whereMap)
}

func GetBlogPageConnectionFilterMap(m *model.RootQueryToPageConnectionWhereArgs) map[string]string { // 未完成
	if m == nil {
		return nil
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogPage]
	if !hasEntitySettings {
		return nil
	}

	whereMap := make(map[string]map[string][]string)
	if columnSetting, hasColumnSetting := entitySettings["databaseId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.ID != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], strconv.Itoa(*m.ID))
		}
		if m.In != nil && len(m.In) > 0 {
			var sa []string
			for _, s := range m.In {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.NotIn != nil && len(m.NotIn) > 0 {
			var sa []string
			for _, s := range m.NotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["parentDatabaseId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Parent != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Parent)
		}
		if m.ParentIn != nil && len(m.ParentIn) > 0 {
			var sa []string
			for _, s := range m.ParentIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.ParentNotIn != nil && len(m.ParentNotIn) > 0 {
			var sa []string
			for _, s := range m.ParentNotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["uri"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Name != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Name)
		}
		if m.NameIn != nil && len(m.NameIn) > 0 {
			var sa []string
			for _, s := range m.NameIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["authorId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Author != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], strconv.Itoa(*m.Author))
		}
		if m.AuthorIn != nil && len(m.AuthorIn) > 0 {
			var sa []string
			for _, s := range m.AuthorIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.AuthorNotIn != nil && len(m.AuthorNotIn) > 0 {
			var sa []string
			for _, s := range m.AuthorNotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["authorName"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.AuthorName != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.AuthorName)
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["title"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Title != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Title)
		}
	}

	return map[string]string{
		"filter": ConnectionWhereMapToString(whereMap),
	}
}

func GetBlogBookFilter(id string, idType *model.BookIDType) string {
	if idType == nil {
		return ""
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogBook]
	if !hasEntitySettings {
		return ""
	}

	whereMap := make(map[string]map[string][]string)

	switch *idType {
	case model.BookIDTypeDatabaseID:
		columnSetting, hasColumnSetting := entitySettings["databaseId"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	case model.BookIDTypeID:
		columnSetting, hasColumnSetting := entitySettings["id"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.BookIDTypeSlug:
		columnSetting, hasColumnSetting := entitySettings["slug"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.BookIDTypeURI:
		columnSetting, hasColumnSetting := entitySettings["uri"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	}

	return ConnectionWhereMapToString(whereMap)
}

func GetBlogBookConnectionFilterMap(m *model.RootQueryToBookConnectionWhereArgs) map[string]string { // 未完成
	if m == nil {
		return nil
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogBook]
	if !hasEntitySettings {
		return nil
	}

	whereMap := make(map[string]map[string][]string)
	if columnSetting, hasColumnSetting := entitySettings["databaseId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.ID != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], strconv.Itoa(*m.ID))
		}
		if m.In != nil && len(m.In) > 0 {
			var sa []string
			for _, s := range m.In {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.NotIn != nil && len(m.NotIn) > 0 {
			var sa []string
			for _, s := range m.NotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["parentDatabaseId"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Parent != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Parent)
		}
		if m.ParentIn != nil && len(m.ParentIn) > 0 {
			var sa []string
			for _, s := range m.ParentIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
		if m.ParentNotIn != nil && len(m.ParentNotIn) > 0 {
			var sa []string
			for _, s := range m.ParentNotIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["notIn"] = append(whereMap[columnName]["notIn"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["uri"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Name != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Name)
		}
		if m.NameIn != nil && len(m.NameIn) > 0 {
			var sa []string
			for _, s := range m.NameIn {
				if s != nil && *s != "" {
					sa = append(sa, *s)
				}
			}
			if len(sa) > 0 {
				whereMap[columnName]["in"] = append(whereMap[columnName]["in"], strings.Join(sa, arrayValueSeparator))
			}
		}
	}
	if columnSetting, hasColumnSetting := entitySettings["title"]; hasColumnSetting {
		columnName := columnSetting.Name
		whereMap[columnName] = make(map[string][]string)
		if m.Title != nil {
			whereMap[columnName]["equalTo"] = append(whereMap[columnName]["equalTo"], *m.Title)
		}
	}

	return map[string]string{
		"filter": ConnectionWhereMapToString(whereMap),
	}
}

func GetBlogContentNodeFilter(
	id string,
	idType *model.ContentNodeIDTypeEnum,
	contentType *model.ContentTypeEnum,
) (rpcEntityName string, res string) {
	if idType == nil || contentType == nil {
		return
	}

	entitySettings, hasEntitySettings := util.RpcEntityPreloadMap[util.RpcEntityNames.BlogContentNode]
	if !hasEntitySettings {
		return
	}

	switch *contentType {
	case model.ContentTypeEnumBook:
		rpcEntityName = util.RpcEntityNames.BlogBook
	case model.ContentTypeEnumPage:
		rpcEntityName = util.RpcEntityNames.BlogPage
	case model.ContentTypeEnumPost:
		rpcEntityName = util.RpcEntityNames.BlogPost
	}

	whereMap := make(map[string]map[string][]string)
	switch *idType {
	case model.ContentNodeIDTypeEnumDatabaseID:
		columnSetting, hasColumnSetting := entitySettings["databaseId"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	case model.ContentNodeIDTypeEnumID:
		columnSetting, hasColumnSetting := entitySettings["id"]
		if hasColumnSetting {
			if strId := util.StringIDToString(id); strId != "" {
				columnName := columnSetting.Name
				whereMap[columnName] = map[string][]string{
					"equalTo": []string{strId},
				}
			}
		}
	case model.ContentNodeIDTypeEnumURI:
		columnSetting, hasColumnSetting := entitySettings["uri"]
		if hasColumnSetting {
			columnName := columnSetting.Name
			whereMap[columnName] = map[string][]string{
				"equalTo": []string{id},
			}
		}
	}

	return rpcEntityName, ConnectionWhereMapToString(whereMap)
}
